<template>
  <div class="test">
    <a-button style="margin: 16px;" type="primary" @click="exportTableHandler">表格导出按钮</a-button>
    <br>
    <a-switch size="small" v-model:checked="hiddenSame" @change="hiddenSameChangeHandler" />
    <span>{{ hiddenSame ? '关闭隐藏' : '隐藏相同项' }}</span>
    <a-table :columns="finalColumns" :key="renderIndex" :data-source="finalData" size="middle" :pagination="false"
      :scroll="{ x: 'calc(700px + 50%)', y: 500 }">
      <!-- <a-table :columns="finalColumns" :key="index" :data-source="finalData" size="middle" :pagination="false"> -->
      <template #headerCell="{ column, record }">
        <template v-if="column.dataIndex !== 'name' && !column.children">
          <a-tag color="#E6F8F2" style="color: #00BE7A;width: 60%;">{{ column.title }}</a-tag>
        </template>
      </template> </a-table>
  </div>
</template>

<script setup lang='ts'>
import { cloneDeep, forIn } from 'lodash';
import { onMounted, reactive, ref } from 'vue';
import { any, array, string } from 'vue-types';
import { utils, writeFile } from 'xlsx'

// 定义是否隐藏相同项的开关
let hiddenSame = ref<boolean>(false)

let bcsCompareList = [
  {
    "Id": 91,
    "BcsName": "bcstest123",
    "EceId": 4,
    "ProjectId": 73,
    "PcId": 0,
    "Sid": 0,
    "Content": "{\"year_total\":[2022,2023],\"income\":{\"car_output_rfq\":[100001,10000,110001],\"ir_rate_rfq\":[95,96,-1],\"ir_number_rfq\":[9501,9500,19001],\"car_output\":[8500,8500,17000],\"ir_rate\":[95,95,-1],\"ir_number\":[8075,8075,16150],\"hardware_price\":[{\"Price\":1,\"Percent\":100},{\"Price\":0,\"Percent\":100},{\"Price\":-1,\"Percent\":-1}],\"software_price\":[{\"Price\":0,\"Percent\":100},{\"Price\":0,\"Percent\":100},{\"Price\":-1,\"Percent\":-1}],\"develop_one\":[0,0,0],\"software_service\":[0,0,0],\"hardware_income\":[8075,0,8075],\"software_income\":[0,0,0]},\"three_cost\":{\"hardware_buy_price\":[{\"Price\":10,\"Percent\":100},{\"Price\":0,\"Percent\":100},{\"Price\":-1,\"Percent\":-1}],\"all_buy_cost\":[807500,0,807500],\"supply_developer_money\":[0,0,0],\"three_all_cost\":[80750,0,807500]},\"in_platform\":{\"ark_sw\":[0,0,0],\"ark_develop\":[0,0,0],\"software_tools\":[{\"Price\":0,\"IrNumber\":8075},{\"Price\":0,\"IrNumber\":8075},{\"Price\":0,\"IrNumber\":1}],\"ark_hardware_develop\":[0,0,0],\"drive_platform_price\":[156,156,312],\"stop_platform_price\":[54,54,108],\"base_drive_price\":[7.1,7.1,14.2],\"other_func\":[0,0,0],\"software_platform_dev\":[1753082.5,1753082.5,3506165]},\"cus_cost\":{\"develop_people_cost\":[0,0,0],\"develop_no_people_cost\":[0,0,0],\"cus_project_dev_cost\":[0,0,0]},\"over_head\":{\"period_fee\":[0,0,0]},\"over_view\":{\"all_sales_income\":[0,0,0],\"all_develop_fee\":[1753082.5,1753082.5,3506165],\"all_cost\":[0,0,0],\"tax_profit\":[0,0,0],\"tax_profit_percent\":[0,0,-1]}}",
    "PcName": "",
    "BcsType": "",
    "CarOutput": 17000,
    "Round": 0,
    "Operator": "zhaoshubao",
    "CreatedAt": 1681972574
  },
  {
    "Id": 89,
    "BcsName": "bcstest123",
    "EceId": 4,
    "ProjectId": 73,
    "PcId": 0,
    "Sid": 0,
    "Content": "{\"year_total\":[2022,2023],\"income\":{\"car_output_rfq\":[10000,10000,20000],\"ir_rate_rfq\":[95,95,-1],\"ir_number_rfq\":[9500,9500,19000],\"car_output\":[8500,8500,17000],\"ir_rate\":[95,95,-1],\"ir_number\":[8075,8075,16150],\"hardware_price\":[{\"Price\":0,\"Percent\":100},{\"Price\":0,\"Percent\":100},{\"Price\":-1,\"Percent\":-1}],\"software_price\":[{\"Price\":0,\"Percent\":100},{\"Price\":0,\"Percent\":100},{\"Price\":-1,\"Percent\":-1}],\"develop_one\":[0,0,0],\"software_service\":[0,0,0],\"hardware_income\":[0,0,0],\"software_income\":[0,0,0]},\"three_cost\":{\"hardware_buy_price\":[{\"Price\":0,\"Percent\":100},{\"Price\":0,\"Percent\":100},{\"Price\":-1,\"Percent\":-1}],\"all_buy_cost\":[0,0,0],\"supply_developer_money\":[0,0,0],\"three_all_cost\":[0,0,0]},\"in_platform\":{\"ark_sw\":[0,0,0],\"ark_develop\":[0,0,0],\"software_tools\":[{\"Price\":0,\"IrNumber\":8075},{\"Price\":0,\"IrNumber\":8075},{\"Price\":0,\"IrNumber\":0}],\"ark_hardware_develop\":[0,0,0],\"drive_platform_price\":[156,156,312],\"stop_platform_price\":[54,54,108],\"base_drive_price\":[7.1,7.1,14.2],\"other_func\":[0,0,0],\"software_platform_dev\":[1753082.5,1753082.5,3506165]},\"cus_cost\":{\"develop_people_cost\":[0,0,0],\"develop_no_people_cost\":[0,0,0],\"cus_project_dev_cost\":[0,0,0]},\"over_head\":{\"period_fee\":[0,0,0]},\"over_view\":{\"all_sales_income\":[0,0,0],\"all_develop_fee\":[1753082.5,1753082.5,3506165],\"all_cost\":[0,0,0],\"tax_profit\":[0,0,0],\"tax_profit_percent\":[0,0,-1]}}",
    "PcName": "",
    "BcsType": "",
    "CarOutput": 17000,
    "Round": 0,
    "Operator": "zhaoshubao",
    "CreatedAt": 1681972000
  }
]
let test = JSON.parse('{\"year_total\":[2022,2023],\"income\":{\"car_output_rfq\":[100001,10000,110001],\"ir_rate_rfq\":[95,96,-1],\"ir_number_rfq\":[9501,9500,19001],\"car_output\":[8500,8500,17000],\"ir_rate\":[95,95,-1],\"ir_number\":[8075,8075,16150],\"hardware_price\":[{\"Price\":1,\"Percent\":100},{\"Price\":0,\"Percent\":100},{\"Price\":-1,\"Percent\":-1}],\"software_price\":[{\"Price\":0,\"Percent\":100},{\"Price\":0,\"Percent\":100},{\"Price\":-1,\"Percent\":-1}],\"develop_one\":[0,0,0],\"software_service\":[0,0,0],\"hardware_income\":[8075,0,8075],\"software_income\":[0,0,0]},\"three_cost\":{\"hardware_buy_price\":[{\"Price\":10,\"Percent\":100},{\"Price\":0,\"Percent\":100},{\"Price\":-1,\"Percent\":-1}],\"all_buy_cost\":[807500,0,807500],\"supply_developer_money\":[0,0,0],\"three_all_cost\":[80750,0,807500]},\"in_platform\":{\"ark_sw\":[0,0,0],\"ark_develop\":[0,0,0],\"software_tools\":[{\"Price\":0,\"IrNumber\":8075},{\"Price\":0,\"IrNumber\":8075},{\"Price\":0,\"IrNumber\":1}],\"ark_hardware_develop\":[0,0,0],\"drive_platform_price\":[156,156,312],\"stop_platform_price\":[54,54,108],\"base_drive_price\":[7.1,7.1,14.2],\"other_func\":[0,0,0],\"software_platform_dev\":[1753082.5,1753082.5,3506165]},\"cus_cost\":{\"develop_people_cost\":[0,0,0],\"develop_no_people_cost\":[0,0,0],\"cus_project_dev_cost\":[0,0,0]},\"over_head\":{\"period_fee\":[0,0,0]},\"over_view\":{\"all_sales_income\":[0,0,0],\"all_develop_fee\":[1753082.5,1753082.5,3506165],\"all_cost\":[0,0,0],\"tax_profit\":[0,0,0],\"tax_profit_percent\":[0,0,-1]}}')

let renderIndex = ref(0)
// 定义变量接收最终的表头信息
let finalColumns = reactive<Array<any>>([])
// 定义变量存储最终的表格内部数据
let finalData = reactive<Array<any>>([])

// 定义数据处理的函数
const dealBcsCompareListDataFun = (compareList: Array<any>, isHiddenSame: boolean) => {

  let yearColumns: Array<any> = []
  let tableContent: Array<any> = []

  compareList.forEach((item, index) => {
    // 得到每一项的年份数据
    // console.log('测试当前项',item);
    let { tableHeader, tableBody } = dealContentDataFun(JSON.parse(item.Content), item.Id)
    yearColumns.push(tableHeader)
    // 得到每一项的表格数据
    if (index == 0 && tableContent.length <= 0) {
      tableContent = cloneDeep(tableBody)
    } else {
      tableContent.forEach(itemRow => {
        let sameObj = tableBody.filter(itm => itm.basicName == itemRow.basicName)[0]
        Object.assign(itemRow, sameObj)
      })
    }
  })
  yearColumns.unshift({
    title: 'BCS版本',
    dataIndex: 'name',
    key: 'name'
  })
  console.log('完整表头数据', yearColumns);
  console.log('完整表体', tableContent);

  // 当打开隐藏相同项的开关时需要对数据进行再一次处理，

  let yearArr: Array<string> = []
  if (isHiddenSame) {
    // 首先拿到所有的年份信息
    yearColumns.forEach((item) => {
      if (item.children && item.children.length > 0) {
        item.children.forEach((itm: any) => {
          if (!yearArr.includes(itm.title.toString())) {
            yearArr.push(itm.title.toString())
          }
        })
      }
    })

    let hiddenContent = cloneDeep(tableContent)

    let arr: Array<any> = []
    // 处理内容信息
    hiddenContent.forEach((item, index) => {
      delete item.name
      delete item.basicName
      console.log('每一项', item);

      let sign = Object.values(item)[0]
      let allRepeat = Object.values(item).every(itm => {
        return itm == sign
      })

      // console.log('是否重复');
      if (allRepeat) {
        arr.push(index)
      } else {
        yearArr.forEach(year => {
          // 存储每个对象对应年份的属性名
          let compareItemDataIndexList = []
          // 存储每个对象对应年份的属性值
          let compareItemDataList = []
          for (const dataIndex in item) {
            if (dataIndex.includes(year)) {
              compareItemDataIndexList.push(dataIndex)
              compareItemDataList.push(item[dataIndex])
            }
          }
          // 标志为，用以对比属性值数组当中的每项是都相同
          let itemSign = Object.values(compareItemDataList)[0]
          // 判断数组中的每一项是否都是相同的值
          let itemRepeat = Object.values(compareItemDataList).every(itemData => itemData == itemSign)
          if (itemRepeat) {
            // 此时说明这个对象中同一年份的不同bcs存在相同的值
            compareItemDataIndexList.forEach(item => {
              tableContent[index][item] = '-'
            })
          }
        })
      }

    })

    tableContent = tableContent.filter((item, index) => {
      return !arr.includes(index)
    })
  }
  return {
    yearColumns,
    tableContent
  }

}

// 当开关发生变化的时触发的回调
const hiddenSameChangeHandler = (checked: boolean) => {
  let { yearColumns, tableContent } = dealBcsCompareListDataFun(bcsCompareList, checked)
  finalColumns = yearColumns
  finalData = tableContent
  renderIndex.value++
}


// 定义一个函数用于处理BCS详情页面当中表格数据中的名字显示
const dealNameDataShow = (name: string) => {
  switch (name) {
    // 收入端部分
    case 'income':
      return '收入端'
    case 'car_output_rfq':
      return '车型产量(RFQ)'
    case 'ir_rate_rfq':
      return '搭载率(RFQ)'
    case 'car_output':
      return '车型产量'
    case 'ir_number_rfq':
      return '搭载量(RFQ)'
    case 'car_output':
      return '车型产量(调整)'
    case 'ir_rate':
      return '搭载率(调整)'
    case 'ir_number':
      return '搭载量(调整)'
    case 'hardware_price':
      return '硬件单价'
    case 'software_price':
      return '软件授权单价'
    case 'develop_one':
      return '开发费一次性补偿'
    case 'software_service':
      return '软件服务费'
    case 'hardware_income':
      return '硬件收入'
    case 'software_income':
      return '软件授权收入'

    // 第三方成本部分
    case 'three_cost':
      return '第三方成本'
    case 'hardware_buy_price':
      return '硬件采购单价'
    case 'all_buy_cost':
      return '总硬件采购成本'
    case 'supply_developer_money':
      return '供应商开发费'
    case 'three_all_cost':
      return '第三方总成本'

    // 内部平台部分 
    case 'in_platform':
      return '内部平台'
    case 'ark_sw':
      return 'ARK SW工具链分摊'
    case 'ark_develop':
      return 'ARK研发人员分摊'
    case 'software_tools':
      return '软件工具授权费'
    case 'ark_hardware_develop':
      return 'ARK硬件平台开发平摊费'
    case 'drive_platform_price':
      return '行车平台软件分摊单价'
    case 'stop_platform_price':
      return '泊车平台软件分摊单价'
    case 'base_drive_price':
      return '基础行车功能分摊单价'
    case 'other_func':
      return '其他功能分摊'
    case 'software_platform_dev':
      return '软件平台开发分摊费'

    // 客户项目研发成本部分
    case 'cus_cost':
      return '客户项目研发成本'
    case 'develop_people_cost':
      return '研发人力成本'
    case 'develop_no_people_cost':
      return '研发非人力成本'
    case 'cus_project_dev_cost':
      return '客户项目研发成本'

    // 期间成本部分
    case 'over_head':
      return '期间成本'
    case 'period_fee':
      return '期间费用'

    // 核算总览部分
    case 'over_view':
      return '核算总览'
    case 'all_develop_fee':
      return '总研发费用'
    case 'all_sales_income':
      return '总销售收入'
    case 'all_cost':
      return '总成本'
    case 'tax_profit':
      return '息税前利润'
    case 'tax_profit_percent':
      return '息税前利润百分比'
    default:
      return '未知'
  }
}


// 定义一个函数专门处理Content数据
const dealContentDataFun = (listData: any, bcsId: string) => {
  let tableHeader: {
    title: string,
    children: Array<any>
  } = {
    title: bcsId,
    children: []
  }
  listData.year_total.forEach((year: number) => {
    tableHeader.children.push({

      title: year,
      dataIndex: bcsId + year.toString(),
      key: bcsId + year.toString(),
      align: 'center'
    })
  })

  // console.log('单个表头', tableHeader);

  // 遍历对象
  let tableBody: Array<any> = []
  for (const firstItem in listData) {
    // console.log(firstItem);
    if (firstItem == 'year_total') continue
    for (const secondItem in listData[firstItem]) {
      let secondObj = {
        name: dealNameDataShow(secondItem),
        basicName: secondItem,
      }
      listData[firstItem][secondItem].forEach((thirdItem: any, idx: number) => {
        if (idx < listData.year_total.length) {
          if (typeof thirdItem == 'object') {
            thirdItem = Object.values(thirdItem).reduce((pre, cur) => {
              return (pre as number) * (cur as number)
            }, 1)
          }
          Reflect.set(secondObj, bcsId + listData.year_total[idx].toString(), thirdItem)
        }
      })
      tableBody.push(secondObj)
    }
  }



  return {
    tableHeader,
    tableBody
  }

}

const transData = (columns, tableList) => {
  const obj = columns.reduce((acc, cur) => {
    console.log('测试', acc, cur);

    if (!acc.titles && !acc.keys) {
      acc.titles = [];
      acc.keys = [];
      acc.secondTitles=[]
      acc.secondKeys=[]
    }
 
    acc.titles.push(cur.title);
    // if (cur.key=='name') {
    //   acc.keys.push('name')
    //   acc.titles.push('BCS名称')
    // }
    // // acc.keys.push(cur.dataIndex)
    if (cur.children) {
      cur.children.forEach(item => {
        acc.secondTitles.push(item.title)
        acc.secondKeys.push(item.dataIndex);

      })
    }
    acc.keys.push(cur.dataIndex);
    return acc;
  }, {});
  console.log('对象', obj);

  const tableBody = tableList.map(item => {
    return obj.secondKeys.map(key => item[key]);
  });
  return [obj.titles, ...tableBody];
}

// 导出表格数据的回调函数
const exportTableHandler = () => {
  const tableData = transData(
    finalColumns,
    finalData
  );
  // 将一组 JS 数据数组转换为工作表
  const ws = utils.aoa_to_sheet(tableData);
  // 创建 workbook
  const wb = utils.book_new();
  // 将 工作表 添加到 workbook
  utils.book_append_sheet(wb, ws, 'Sheet1');
  // 将 workbook 写入文件
  writeFile(wb, 'table.xlsx');
}

onMounted(() => {
  let { yearColumns, tableContent } = dealBcsCompareListDataFun(bcsCompareList, hiddenSame.value)
  finalColumns = yearColumns
  finalData = tableContent
  renderIndex.value++
  // dealContentDataFun(test, '91')
})
</script>

<style lang="less" scoped>
:deep(.ant-table-thead>tr>th) {

  // color: #749dee !important;
  background: #fff;

}
</style>